package cronx

import (
	"sync"
	"time"

	"github.com/robfig/cron/v3"
)

var (
	parserOnce sync.Once
	parser     *CronParser
)

type CronParser struct {
	parser cron.Parser
}

func NewCronParser() *CronParser {
	parserOnce.Do(func() {
		p := cron.NewParser(
			cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor,
		)
		parser = &CronParser{
			parser: p,
		}
	})
	return parser
}

func (c *CronParser) NextTime(cron string, t time.Time) (time.Time, error) {
	schedule, err := c.parser.Parse(cron)
	if err != nil {
		return t, err
	}
	return schedule.Next(t), nil
}

func (c *CronParser) Next(cron string, t time.Time, count int) ([]time.Time, error) {
	schedule, err := c.parser.Parse(cron)
	if err != nil {
		return nil, err
	}
	var timeList []time.Time
	cur := t
	for i := 0; i < count; i++ {
		n := schedule.Next(cur)
		timeList = append(timeList, n)
		cur = n
	}
	return timeList, nil
}
